\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[francais]{babel}
\usepackage[french, linesnumbered, algoruled]{algorithm2e} % pour installer : sudo apt-get install texlive-science
\usepackage[T1]{fontenc}
\usepackage{ifpdf}
\usepackage{array}
\usepackage{lmodern}
\usepackage{graphicx}


\marginparwidth 0pt
\oddsidemargin  0pt
\evensidemargin  0pt
\marginparsep 0pt

\topmargin   0pt

\textwidth   6.5in
\textheight  8.5 in


\renewcommand{\familydefault}{\sfdefault}

\title{Rapport de projet M1 Informatique - Réseaux}
\author{Baptiste Saleil \& Julien Pagès}
\date{\today}
\ifpdf
	\pdfinfo 
	{
		/Author (Baptiste Saleil - Julien Pages)
		/Title (Rapport de projet)
		/Subject (Reseau)
		/Keywords ()
		/CreationDate (\today)
	}
\fi
\begin{document}
	% Page de titre
	\maketitle
	\ \\ \\ \\
	\begin{center}\includegraphics[scale=0.45]{img/um2.png}\end{center}
	\vfill
	\begin{center}Rapport réalisé en \LaTeX\end{center}
	
	\thispagestyle{empty}
	\newpage
	
	% Sommaire
	\tableofcontents
	\newpage
	
	\section{Introduction}
	Ce rapport présente le travail de deux étudiants, Baptiste Saleil et Julien Pagès, sur un sujet de réseaux de master 1 informatique à l'Université Montpellier 2. \\
	Le sujet consiste à représenter une grille, ici de 4x4, avec un curseur positionné à l'intérieur. Cette grille est stockée sur une application serveur. \\ A chaque fois qu'un client se connecte, il doit pouvoir visualiser cette grille en temps réel, et donc connaître à tout moment la position du curseur. \\
	Les clients peuvent également prendre le contrôle de la grille. Une file d'attente est donc créée pour passer la main aux clients, chacun leur tour. \\
	Lorsque qu'un client prend le contrôle de la grille, il a le droit d'effectuer un certain nombre de mouvement sur le curseur (ce nombre est paramétrable) avant de perdre le contrôle au profit du prochain client dans la liste d'attente. \\
	Les mouvements effectués sur la grille sont conservés dans un historique qui s'effacera tous les n mouvements (paramétrable également). \\
	\ \\ Le rapport ci-dessous présente uniquement l'application console. L'interface sera expliqué dans une partie qui lui est dédiée.
	
	\section{Manuel}
	Cette partie vous présente comment s'utilisent nos applications, serveur et client.
	\subsection{Serveur}
		\paragraph{Compilation} \ \\ \\
		Un makefile est présent dans le dossier du serveur. \\
		Il suffit alors d'exécuter la commande \textit{make} pour générer l'exécutable à partir des sources.
		\paragraph{Execution} \ \\ \\
		Pour exécuter l'application serveur, il suffit de lancer l'exécutable dans un terminal : \textit{./serveur}. Cependant, quelques options doivent être passées en paramètre.
		Si trop ou trop peu d'arguments sont passés, un petit manuel sera affiché pour vous rappeller à quoi correspondent les arguments, et combien il en faut. \\
		\begin{itemize}
			\item{\textbf{\underline{Port}} : Représente le port utilisé par le serveur. C'est le seul argument obligatoire, les arguments ci-dessous sont optionnels.}
			\item{\textbf{Nombre de mouvements maximum} : Correspond au nombre de mouvements qu'un client qui a le contrôle, peut faire sur le curseur de la grille avant de perdre le contrôle.}
			\item{\textbf{Nombre de clients maximum} : Ce paramètre renseigne le nombre de clients maximum connectés en même temps sur le serveur. Les autres clients sont refusés.}
			\item{\textbf{Historique de la grille} : Correspond au nombre de mouvements effectués sur le curseur, avant de remettre la grille à zéro (ceci pour une meilleure visibilité).}
		\end{itemize}
		
		Par défaut le serveur se lance (en mode console) avec 3 mouvements maximum dans la grille, 10 clients simultanément connectés, et 5 mouvements gardés dans l'historique de la grille.
		
		\paragraph{Utilisation} \ \\ \\
		Une fois le serveur lancé, l'utilisateur n'a plus besoin d'intéragir avec lui. La seule possibilité qu'il a est de l'arrêter en entrant la commande \textbf{q}. \\
		\ \\
		ATTENTION : Pour que les commandes soient effectives, ils faut les valider avec la touche entrée. (ex : q + entrée)
		
		\paragraph{Exemples}
		\begin{center}\textit{./serveur 10000}\end{center}
		Le serveur sera ici lancé sur le port 10000 avec les valeurs par défaut pour les arguments facultatifs.
		\begin{center}\textit{./serveur 20000 5 10}\end{center}
		Ici, le serveur écoutera le port 20000, permettra 5 mouvements par client, autorisera 10 clients en même temps, et conservera l'historique de grille par défaut.
		\begin{center}\textit{./serveur 30000 4 8 6}\end{center}
		Ici, le serveur écoutera le port 30000, permettra 4 mouvements par client, autorisera 8 clients en même temps, et conservera 6 mouvements avant d'effacer la grille.
		
	\subsection{Client}
		\paragraph{Compilation} \ \\ \\
		Comme pour le serveur, le client embarque son makefile. Une commande \textit{make} suffit donc à générer les exécutables.
		
		\paragraph{Execution} \ \\ \\
		Toujours comme le serveur, pour exécuter un client, il suffit de lancer l'exécutable dans un terminal avec \textit{./client}. Quelques options sont aussi à passer en paramètre.
		Si trop ou pas assez d'arguments sont passés, un petit manuel sera affiché pour vous rappeller à quoi correspondent les arguments, et combien il en faut. \\
		Pour lancer plusieurs clients, il suffit d'exécuter plusieurs fois l'application. \\
		\begin{itemize}
			\item{\textbf{\underline{Hôte}} : Ce paramètre est obligatoire. Il représente l'hôte ou trouver le serveur.}
			\item{\textbf{\underline{Port}} : Second paramètre obligatoire. Il correspond au port par lequel écoute le serveur présent sur l'hôte précédemment renseigné.}
		\end{itemize}
		
		\paragraph{Utilisation} \ \\ \\
		Une fois le client lancé, et connecté au serveur, la grille s'affiche en temps réel.
		L'utilisateur peut alors intéragir avec le programme client : \\
			\begin{itemize}
				\item{\textbf{q} : Pour quitter le client de façon propre.}
				\item{\textbf{p} : Pour prendre le contrôle de la grille. Cette action a pour effet de donner le contrôle à l'utilisateur, ou de l'ajouter à la liste d'attente des clients désirant prendre le contrôle.}
				\item{\textbf{h} : Pour effectuer un mouvement vers le haut du curseur de la grille. Cette commande est sans effet si l'utilisateur n'a pas le contrôle de la grille.}
				\item{\textbf{b} : Idem pour un mouvement vers le bas.}
				\item{\textbf{g} : Idem pour un mouvement vers la gauche.}
				\item{\textbf{d} : Idem pour un mouvement vers a droite.}
			\end{itemize}
		\ \\
		ATTENTION : Pour que les commandes soient effectives, ils faut les valider avec la touche entrée. (ex : p + entrée)
		
		\paragraph{Exemples}
		\begin{center}\textit{./client localhost 10000}\end{center}
		Le client sera lancé et cherchera le serveur en local sur le port 10000.
		\begin{center}\textit{./client 192.168.0.24 45654}\end{center}
		Ici, le client cherchera le serveur à l'adresse 192.168.0.24 sur le port 45654
	
	\section{Architecture}
		Pour le développement de nos deux applications, nous avons utilisé 3 principes : l'architecture \textbf{client-serveur}, les \textbf{threads}, et les \textbf{mutex}.
		\subsection{Serveur}
			Le serveur gère les clients par le principe du client-serveur, en utilisant le protocole TCP. Les clients sont manipulés grâce aux sockets UNIX, et gérés par l'intermédiaire des conteneurs de la STL (list, vector, ...). \\ \\
			Plusieurs thread sont utilisés côté serveur : \\
			\begin{itemize}
				\item{\textbf{Principal} : Le thread principal effectue les tâches générales : Récupération des arguments, initialisation des variables, etc... C'est également lui qui gère l'arrivée des nouveaux clients, en respectant les contraires imposées lors du lancement du serveur (nombre de clients).}
				\item{\textbf{Reception} : Un thread de reception est créé pour chaque client qui se connecte. Ce thread écoute ce qui se passe sur la socket et agit en fonction des paquets envoyés selon notre protocole, ce thread permet une meilleure souplesse dans la gestion des clients.}
				\item{\textbf{Envoi} : Le thread d'envoi envoie à son client la grille actualisée, en indiquant au client si il a le contrôle sur la grille, ou encore si il est en attente de l'avoir.}
				\item{\textbf{Commandes} : Le thread commandes attends des commandes de l'utilisateur (ici sur le clavier) et agit en conséquence, ce thread permet de terminer proprement l'application serveur en fermant la socket publique, et les sockets des différents clients.}
			\end{itemize} \ \\
			Comme dit plus haut, notre application côté serveur utilise des mutex afin de protéger les données partagées par plusieurs threads et/ou clients. En voici la liste : \\
			\begin{itemize}
				\item{\textbf{Mutex des descripteurs} : Ce mutex protège des accès concurrents en écriture sur la liste des descripteurs des sockets privées (celles du circuit virtuel).}
				\item{\textbf{Mutex de la file d'attente} : Ce mutex protège la file d'attente, pour éviter d'avoir des pertes de données.}
				\item{\textbf{Mutex de la grille} : Ce mutex est particulier car il protège la grille, il sert à assurer que le contrôle de la grille est attribué à un seul client, et ce de manière atomique, il reste donc verrouillé jusqu'à ce que le client relâche le contrôle (déconnexion ou plus de mouvements disponibles).}
			\end{itemize}
		\subsection{Client}
			Pour le client, l'architecture client-serveur est bien évidemment également utilisée. Le client gère la connexion grâce aux sockets UNIX. Le client n'utilise pas de mutex étant donné que lui et lui seul se sert de ses données, il ne les partage avec personne.\\
			Cependant, nous avons choisis d'utiliser plusieurs threads pour gérer au mieux les clients de notre application : \\
			\begin{itemize}
				\item{\textbf{Principal} : Le thread principal se charge de récupérer les arguments, d'initialiser les variables et sockets, etc... Lorsque la connexion est effective, il passe la main aux deux threads ci-dessous qui vont chacun réaliser leur tâche. }
				\item{\textbf{Réception/Affichage} : Le thread de reception est chargé de lire en continue sur la socket ce que lui envoie le serveur, et affiche le grille ainsi reçue en temps réel. Il indique également au client son statut : a le contrôle, attends le contrôle, ou visualise simplement.}
				\item{\textbf{Envois/Commande} : Le thread d'envois est chargé de lire les commandes entrées par l'utilisateur sur stdin, ici le clavier, et de les envoyer au serveur en respectant le protocole.}
			\end{itemize}
	
	\section{Protocole d'échange}
	Pour mener à bien ce projet et implémenter au mieux l'architecture client-serveur, nous avons dû mettre en place un protocole d'échange. \\
	
		\subsection{Grille}
		Nous avons choisis de représenter la grille sous forme d'un tableau, qui serait ensuite découpé pour l'affichage côté client. Ce tableau est composé de 16 caractères représentant chacun l'état d'une des cases de la grille. La grille est parfois remise à zéro par le serveur, pour assurer une meilleure visibilité. \\
		 Les valeurs possible sont les suivantes :
		\begin{itemize}
			\item{\textbf{'0'} : La case est vide.}
			\item{\textbf{'1'} : La case contient le curseur.}
			\item{\textbf{'*'} : La case a contenu le curseur (historique).}
		\end{itemize}
		La grille pourra par exemple être représentée de la manière suivante : \textit{"**010*0*0***0000"} qui correspond à : \\
		\begin{center}
		\begin{tabular}{|c|c|c|c|}
			\hline
   			* & * & 0 & 1 \\
   			\hline
   			0 & * & 0 & * \\
   			\hline
			0 & * & * & * \\
			\hline
			0 & 0 & 0 & 0 \\
			\hline
		\end{tabular}
		\end{center}
		La grille est ainsi envoyée au client, suivi d'un caractère 'c' ou 'a' si le client a respectivement le contrôle, ou est en attente du contrôle. Ce cartère servira au client, qui va modifier l'affichage de la grille en ajoutant un petit manuel destiné à l'utilisateur.
		
		\subsection{Commandes}
		Pour faire dialoguer nos deux applications, serveur et client, nous avous décidé de simplifier au maximum le protocole. En effet, le client envoie un caractère au serveur, qui va a son tour l'interpréter comme une commande. Voici la liste des commandes utilisées dans notre protocole : \\
		\begin{itemize}
			\item{\textbf{'p'} : Le client désire prendre le contrôle de la grille.}
			\item{\textbf{'h'} : Le client désire bouger le curseur vers le haut.}
			\item{\textbf{'b'} : Le client désire bouger le curseur vers le bas.}
			\item{\textbf{'g'} : Le client désire bouger le curseur vers la gauche.}
			\item{\textbf{'d'} : Le client désire bouger le curseur vers la droite.}
		\end{itemize}
		
		\subsection{Synthèse}
		Notre protocole est ainsi simplifié au maximum. \\
		Du serveur vers le client, on envoie uniquement un tableau représentant la grille complétée d'un caractère d'indication. \\
		Du client vers le serveur, on envoie uniquement un caractère correspondant à une commande qui sera gérée directement côté serveur. \\
		
	\section{Schémas algorithmiques}
		\subsection{Serveur}
		
			Voici le thread principal du serveur : il créé le serveur, gère les connexions entrantes, et délègue à deux autres threads le traitement du client.\\
			\begin{algorithm}
			\Deb
			{
				$Récupération\ arguments$\;
				$Création\ socket\ publique$\;
				$file = listen()$\;
				$pthread\_create(threadCommande)$\;
				\Tq{$vrai$}
				{
					$descripteurCV = accept()$\;
					\eSi{$nbClientsConnectés < nbClientsMax $}
					{
						$pthread\_mutex\_lock(mutexDescripteurs)$\;
						$pthread\_create(threadEnvoi)$\;
						$pthread\_create(threadReception)$\;
						$pthread\_mutex\_unlock(mutexDescripteurs)$\;
					}
					{
						$close(descripteurCV)$\;
					}
				}
			}
			\caption{Schéma algorithmique de la boucle principale du serveur}
			\end{algorithm}
		
		\newpage
		\subsection{Client}
			Voici le thread principal du client : il créé le serveur et délègue ensuite la gestion de l'affichage à un thread, et la gestion des commandes à un autre thread. Il attends ensuite la terminaison du thread des commandes, d'où proviendra la demande de fermeture du client.
			\begin{algorithm}
			\Deb
			{
				$Récupération\ arguments$\;
				$Création\ socket$\;
				$Désigner\ le\ serveur$\;
				$connect()$\;
				$pthread\_create(threadAffichage)$\;
				$pthread\_create(threadCommandes)$\;
				$pthread\_join(threadCommandes)$\;
				$close(descripteurClient)$ \;
			} 
			\caption{Schéma algorithmique du thread principal du client}
			\end{algorithm}
	
	\section{Difficultés rencontrées}
	Comme dans tout projets, nous avons été confrontés à différentes difficultés : 
		\begin{itemize}
			\item{\textbf{Architecture} : L'architecture générale de l'application nous a posé problème. Il nous a fallu ainsi un certain temps de réflexion afin de penser notre programme de la meilleure façon selon nous. Malgré ça, tout au long de la réalisation, il nous a fallu modifier certaines parties de notre architecture comme les variables globales, les paramètres des threads, etc...}
			\item{\textbf{Déconnexion brutale d'un client} : Notre application serveur gère parfaitement la connexion/déconnexion des clients à condition qu'elle soit faite proprement (l'utilisateur entre la touche 'q' pour quitter). Si on lance un client, qu'il se connecte au serveur, et qu'on le ferme de façon brutale (ctrl+c par exemple, on peut imaginer un bug du système pendant que le client tourne), le serveur panique et se ferme. Ce bug est toujours présent dans la version finale et nous n'en avons pas trouvé l'origine, malgré un bon moment passé dessus.}
			
			\item{\textbf{Stockage des clients} : Le stockage des clients nous a posé problème. En effet, nous avons d'abord choisis d'utiliser les vector de la STL pour les stocker. Notre application serveur agissait de manière un peu étrange, comme si l'ordre des éléments n'était pas conservé, alors que c'est bien le cas avec un vector. Après avoir perdu du temps dessus, nous avons finis par utiliser les list (toujours la STL) ce qui a résolu notre problème. Ce problème est un détail mais il nous a fait perdre beaucoup d'heures (Pour le trouver et le résoudre).}
			
			\item{\textbf{Gestion de l'attribution du contrôle} : La gestion du contrôle a été compliquée à gérer lors de son implémentation, car plusieurs problèmes se posaient. En particulier la déconnexion d'un client alors qu'il est en file d'attente, et l'attribution du contrôle en toutes circonstances sans omettre un client ayant fait la demande. Ce problème a été résolu grâce à une liste de la STL, ainsi que diverses procédures de mise à jour de l'attribution du contrôle.}
			
			\item{\textbf{Synchronisation} : Comme dans tout projet à plusieurs, la synchronisation du travail n'est pas chose aisée. Pour résoudre le problème dès le début, nous avons utilisé un gestionnaire de version (Subversion) ainsi que des outils de developpement collaboratif (Gobby pour l'edition, Gtalk pour la discussion)}
		\end{itemize}
	
	\section{Interface graphique}
	Pour faciliter l'utilisation des deux applications, nous avons choisis d'implémenter des interfaces graphiques. \\
		\subsection{Technique}
			L'interface à été compilée et fonctionne avec Qt 4.7. \\
			Les makefile embarqués sont générés par Qt. \\
			Notre implémentation est une simple surcouche aux programmes en console ce qui implique que celles-ci soient compilées et présentes dans le dossier prévu. \\
			La librairie Qt met à notre disposition la classe \textbf{QProcess} qui permet de lancer des programmes externes et intéragir avec eux. \\
			Nous avons donc lancé les programmes console de cette manière, puis nous avons redirigé \textbf{stdout} (la sortie standard) sur une zone de texte pour afficher le log (debug) et nous avons fait correspondre les boutons de l'interface avec \textbf{stdin} (l'entrée standard) pour agir sur le programme.
		
		\subsection{Compilation}
			Un makefile est fourni avec le serveur et avec le client. Un simple \textit{make} donc suffit à générer les exécutables.
		
		\subsection{Utilisation}
			ATTENTION : Les programmes console doivent êtres compilés dans leur dossiers respectifs pour que l'interface fonctionne. (Un message d'avertissement sera affiché dans le cas contraire)
			\paragraph{Serveur} \ \\
			L'utilisation du serveur est aisée. Une fois compilé et lancé, il suffit d'entrer le port, le nombre de mouvements maximum, le nombre de clients maximum, et le nombre de mouvements avant effacement (les arguments donc) dans les widgets prévus à cet effet, puis de cliquer sur le bouton \textbf{lancer}. \\
			Le serveur se lance alors et affiche son log dans la zone de texte prévue à cet effet. \\
			La fermeture propre est gérée par une simple fermeture de la fenêtre par la croix.
			\paragraph{Client} \ \\
			Le client graphique est un petit peu plus complexe. Une fois compilé et lancé, il faut dans un premier temps entrer l'hôte et le port (les arguments donc) dans les widgets prévus à cet effet avant de cliquer sur le bouton \textbf{lancer}. \\
			Une fois le client connecté, la grille est affichée en temps réel, et le log est écrit dans la zone de texte prévue à cet effet. \\
			L'utilisateur peut alors cliquer sur le bouton \textbf{prendre controle} pour demander au serveur de prendre le contrôle de la grille. L'utilisateur sera alors informé de sa prise de contrôle ou de sa mise en file d'attente. \\
			Lorsque l'utilisateur contrôle la grille, il a alors à sa disposition 4 boutons, \textbf{haut, bas, gauche et droite}, lui permettant de déplacer le curseur dans la grille.\\
			La fermeture propre est gérée par une simple fermeture de la fenêtre par la croix.			
	
	\section{Captures}
		\subsection{Console}
			Pour les applications en lignes de commandes, on mettra uniquement la sortie texte, elle a été obtenue en redirigant stdout dans un fichier.
			\paragraph{serveur}  \ \\
			
			\fbox{\begin{minipage}{1\textwidth}
          
				\textit{Mouvements maximum : 3, nombre de clients maximum connectes en meme temps : 10 \\
				Mouvements avant reinitialisation : 5\\
				Serveur en attente sur le port 10000\\
				liste : 0clients : 10\\
				Client connecté : 3066051440\\
				Envoi de la grille au client : 4\\
				Message reçu de 4, controle = -1\\
				Un client veut prendre le controle : 4\\
				Prise de controle de la grille par le client : 4\\
				Envoi de la grille au client : 4\\
				Message reçu de 4, controle = 4\\
				Commande : b\\
				Mouvement vers le bas\\
				Il reste 2 mouvements au client.\\
				Envoi de la grille au client : 4} \\
				
				\end{minipage}} \ \\
			
				Le serveur est lancé sur le port 10000 comme ceci : \textbf{./server 10000}\\
				Un client se connecte ensuite et effectue quelques mouvements, bien sûr pour des questions de place et lisibilité tout n'apparaît pas dans cette capture.
			\newpage
			\paragraph{client} \ \\ Voici l'application cliente correspondant à la sortie du serveur ci dessus. \\
			\fbox{\begin{minipage}{1\textwidth}
				\textit{Connexion reussie \\
				Vous visualisez seulement.\\
				Grille : \\
				1000\\
				0000\\
				0000\\
				0000\\
				Demande de prise de controle\\ \\
				Vous avez le controle de la grille.\\
				h : haut, b : bas, d : droite, g : gauche.\\
				Grille : \\
				$*$000\\
				1000\\
				0000\\
				0000\\ \\
				Vous avez le controle de la grille.\\
				h : haut, b : bas, d : droite, g : gauche.\\
				Grille : \\
				$*$000\\
				$*$000\\
				1000\\
				0000}\\
			\end{minipage}} \ \\
				
				Voici un condensé correspondant au lancement d'un client, à une prise de contrôle ainsi que l'illustration de l'historique de la grille qui fonctionne. \\
				Bien sûr, l'affichage est écrasé à chaque fois pour que l'utilisateur ne visualise qu'une seule grille.

		\newpage
		\subsection{Graphique}
			Voici côte à côte le serveur et le client qui est connecté dessus et qui possède le contrôle sur la grille : \\
			
			\includegraphics[scale=0.45]{img/gui.png}
	\section{Conclusion}
	Ce projet a donc été l'occasion de travailler à plusieurs sur un problème concret de réseaux. Ceci nous a apporté des compétences en coordination : la programmation système sous UNIX est complexe, et il a donc fallu utiliser correctement des outils de synchronisation et beaucoup de communication pour être perpétuellement à jour de l'avancement.
	Cela nous a également permit de mieux appréhender les différents problèmes liés à la programmation système tels que : la synchronisation, la protection en écriture via les mutex etc. \\
	 Le fait que l'application devait être multi-utilisateurs en réseaux a permis de concevoir une architecture pour répondre à ce problème, et de l'implémenter via la programmation système sous Linux. \\
	 Ce projet a donc été enrichissant dans l'apprentissage du travail en équipe et du point de vue conception et réalisation.    
	
\end{document}

